package org.naxx.security.testng.parsing.tck;

import java.io.File;
import java.io.FilenameFilter;
import java.util.HashSet;
import java.util.Set;

import org.apache.log4j.Logger;
import org.naxx.security.Main;
import org.naxx.security.parser.validation.SchemaValidator;
import org.naxx.security.testng.SpringContextAware;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class ValidateMandatoryTckFilesAgainstXmlSchema extends SpringContextAware {
	
	private static final Logger logger = Logger
			.getLogger(ValidateMandatoryTckFilesAgainstXmlSchema.class);
	
	/* List of files we know in advance are invalid as defined by TCK */
	private Set<String> invalidSet = new HashSet<String>();
	private Set<String> tckSets = new HashSet<String>();

	@BeforeClass
	@Override
	public void setUp() throws Exception {
		super.setUp();
		this.invalidSet.add("IIA004Policy.xml");
		this.invalidSet.add("IIA005Policy.xml");
		this.tckSets.add("tck/II/A");
		this.tckSets.add("tck/II/B");
		this.tckSets.add("tck/II/C");
		this.tckSets.add("tck/II/D");
		this.tckSets.add("tck/II/E");
	}

	@AfterClass(alwaysRun=true)
	@Override
	public void tearDown() throws Exception {
		super.tearDown();
	}
	
	@Test(groups={"parsing"})
	public void validateMandatoryTckFiles() throws Exception {
		for(String tckSet : this.tckSets) {
			this.validate(tckSet);
		}
	}
	
	private void validate(String folder) throws Exception {
		SchemaValidator validator = Main.getRepository().getService(SchemaValidator.class);
		File[] policyFiles = new File(folder).listFiles(new FilenameFilter() {
			public boolean accept(File dir, String name) {
				return name.endsWith("Policy.xml") && 
					!ValidateMandatoryTckFilesAgainstXmlSchema.this.invalidSet.contains(name);
			}
		});
		for (int i = 0; i < policyFiles.length; i++) {
			File policyFile = policyFiles[i];
			String testId = policyFile.getName().substring(0, policyFile.getName().indexOf("Policy"));
			File requestFile = new File(policyFile.getParent() + File.separator + testId + "Request.xml");
			File responseFile = new File(policyFile.getParent() + File.separator + testId + "Response.xml");
			
			try {
				validator.validate(policyFile);
			} catch (Exception e) {
				logger.warn("Exception while validating '" + policyFile.getName() + "'", e);
				throw e;
			}
			try {
				validator.validate(requestFile);
			} catch (Exception e) {
				logger.warn("Exception while validating '" + requestFile.getName() + "'", e);
				throw e;
			}
			try {
				validator.validate(responseFile);
			} catch (Exception e) {
				logger.warn("Exception while validating '" + responseFile.getName() + "'", e);
				throw e;
			}
		}
	}
}
